<?php

class oauthcallbackActions extends sfActions {

    public function executeCallGoogleLogin(sfWebRequest $request){
        $scope1="https://www.googleapis.com/auth/userinfo.email";
        $scope2="https://www.googleapis.com/auth/userinfo.profile";

        $url="";
        $url.="https://accounts.google.com/o/oauth2/auth";
        $url.="?scope=".urlencode($scope1)."+".urlencode($scope2);
        $url.="&state=practil";
        $url.="&access_type=online";
        $url.="&redirect_uri=".urlencode($this->getController()->genUrl('@oauthcallbackGoogleLogin',true));
        $url.="&response_type=code";
        $url.="&client_id=".sfConfig::get('app_google_client_id');

        $this->redirect($url);
    }

    public function executeCallFacebookLogin(sfWebRequest $request){
        $facebook = new Facebook(array(
          'appId'  => sfConfig::get('app_facebook_app_id'),
          'secret' => sfConfig::get('app_facebook_app_secret'),
        ));
        $user = $facebook->getUser();

        if($user){
          try{
            $user_profile = $facebook->api('/me');
          }catch(FacebookApiException $e){
            error_log($e);
            $user = null;
          }
        }

        $params = array(
          'scope' => 'email, user_birthday',
          'redirect_uri' => $this->getController()->genUrl('@oauthcallbackFacebookLogin',true)
        );
        $this->redirect($facebook->getLoginUrl($params));
    }

    public function executeGoogleLogin(sfWebRequest $request){
        $code = $request->getParameter('code');
        $state = $request->getParameter('state');
        $handle_error = $request->getParameter('error');

        if($state!='practil'){ $this->forward404(); }

        if($handle_error!=''){
            $this->getUser()->setFlash('message',$handle_error);
            return $this->redirect('@loginAuth');
        }else{
            $postdata = http_build_query(
                array(
                    'code' => $code,
                    'client_id' => sfConfig::get('app_google_client_id'),
                    'client_secret' => sfConfig::get('app_google_client_secret'),
                    'redirect_uri' => urldecode($this->getController()->genUrl('@oauthcallbackGoogleLogin',true)),
                    'grant_type' => 'authorization_code'
                )
            );
            $opts = array('http' =>
                array(
                    'method'  => 'POST',
                    'header'  => 'Content-type: application/x-www-form-urlencoded\r\n',
                    'content' => $postdata
                )
            );
            $context  = stream_context_create($opts);
            $result = @file_get_contents('https://accounts.google.com/o/oauth2/token', false, $context);

            if($result === FALSE){
                $this->getUser()->setFlash('message','Oops, ha ocurrido un error. Intenta nuevamente.');
                return $this->redirect('@loginAuth');
            }else{
                $json = json_decode($result);
                $access_token = $json->{'access_token'};

                $postdata = http_build_query(
                    array(
                        'access_token' => $access_token
                    )
                );

                $userinfo = file_get_contents('https://www.googleapis.com/oauth2/v1/userinfo'."?".$postdata);
                $json_userinfo = json_decode($userinfo);

                /* ingresa o registra usuario Google */
                try {
                    $this->ingresaRegistraGoogleUser($json_userinfo);
                } catch (Exception $exc) {
                    error_log($exc->getTraceAsString());
                    $this->getUser()->setFlash('message','Oops, ha ocurrido un error. Intenta nuevamente.');
                    return $this->redirect('@loginAuth');
                }

                /* si existe una cuenta practil con el mismo correo te pregunta si deseas enlazar las cuentas */
                $c = new Criteria();
                $c->add(UsuarioPeer::ES_ASOCIADO_GOOGLE, 0);
                $c->add(UsuarioPeer::EMAIL, $json_userinfo->{'email'});
                $objeto = UsuarioPeer::doSelectOne($c);
                if(is_object($objeto)){
                    /* pregunta si desea asociar las cuentas */
                    $this->getUser()->setAttribute('json_userinfo',$json_userinfo);
                    $this->redirect('@googleAssocLogin');
                }else{
                    $this->redirect('@account');
                }
            }
        }
    }

    private function ingresaRegistraGoogleUser($json_userinfo){
        /* verificamos si el usuario Google existe */
        $c = new Criteria();
        $c->add(UsuarioPeer::ES_ASOCIADO_GOOGLE, 1);
        $c->add(UsuarioGooglePeer::IDENTIFIER, $json_userinfo->{'id'});
        $c->addJoin(UsuarioPeer::ID, UsuarioGooglePeer::USUARIO_ID);
        $usuario_google = UsuarioGooglePeer::doSelectOne($c);
        if(!is_object($usuario_google)){
            /* si no existe se crea */
            $usuario = new Usuario();
            $usuario->setEmail($json_userinfo->{'email'});
            $usuario->setPassword('');
            $usuario->setNombre($json_userinfo->{'given_name'});
            $usuario->setApellido($json_userinfo->{'family_name'});
            $usuario->setNacionalidad('');
            $usuario->setLocalidad('');
            if($json_userinfo->{'gender'}=='male'){
                $usuario->setSexo('m');
            }else{
                $usuario->setSexo('f');
            }
            $usuario->setFechaNacimiento(null);
            $usuario->setIdioma('es');
            $usuario->setPlataforma('');
            $usuario->setFlag('');
            $usuario->setCredito(0);
            $usuario->setUsuarioTipoId(1);
            $usuario->setEsAsociadoFacebook(0);
            $usuario->setEsAsociadoGoogle(1);
            $usuario->setCreatedAt(time());
            $usuario->save();

            $usuario_google = new UsuarioGoogle();
            $usuario_google->setIdentifier($json_userinfo->{'id'});
            $usuario_google->setName($json_userinfo->{'name'});
            $usuario_google->setGivenName($json_userinfo->{'given_name'});
            $usuario_google->setFamilyName($json_userinfo->{'family_name'});
            $usuario_google->setLink($json_userinfo->{'link'});
            $usuario_google->setPicture($json_userinfo->{'picture'});
            $usuario_google->setGender($json_userinfo->{'gender'});
            $usuario_google->setLocale($json_userinfo->{'locale'});
            $usuario_google->setVerifiedEmail($json_userinfo->{'verified_email'});
            $usuario_google->setUsuario($usuario);
            $usuario_google->save();

            $this->getUser()->setAuthenticated(true);
            $this->getUser()->setAttribute('current_user',$usuario);
        }else{
            /* si existe ingresa y actualiza los datos de google */
            $c = new Criteria();
            $c->add(UsuarioPeer::ID, $usuario_google->getUsuarioId());
            $usuario = UsuarioPeer::doSelectOne($c);

            $usuario_google->setIdentifier($json_userinfo->{'id'});
            $usuario_google->setName($json_userinfo->{'name'});
            $usuario_google->setGivenName($json_userinfo->{'given_name'});
            $usuario_google->setFamilyName($json_userinfo->{'family_name'});
            $usuario_google->setLink($json_userinfo->{'link'});
            $usuario_google->setPicture($json_userinfo->{'picture'});
            $usuario_google->setGender($json_userinfo->{'gender'});
            $usuario_google->setLocale($json_userinfo->{'locale'});
            $usuario_google->setVerifiedEmail($json_userinfo->{'verified_email'});
            $usuario_google->setUsuario($usuario);
            $usuario_google->save();

            $this->getUser()->setAuthenticated(true);
            $this->getUser()->setAttribute('current_user',$usuario);
        }
    }

    public function executeCallGoogleAssoc(sfWebRequest $request){
        if(!$this->getUser()->hasAttribute('json_userinfo')){
            $this->redirect('@account');
        }
        $json_userinfo = $this->getUser()->getAttribute('json_userinfo');
        $c = new Criteria();
        $c->add(UsuarioPeer::EMAIL, $json_userinfo->{'email'});
        $this->usuario_practil = UsuarioPeer::doSelectOne($c);
        $this->json_userinfo = $json_userinfo;
    }

    public function executeCallFacebookAssoc(sfWebRequest $request){
        if(!$this->getUser()->hasAttribute('user_profile')){
            $this->redirect('@mi_cuenta');
        }
        $user_profile = $this->getUser()->getAttribute('user_profile');
        $c = new Criteria();
        $c->add(UsuarioPeer::EMAIL, $user_profile['email']);
        $this->usuario_dialoga = UsuarioPeer::doSelectOne($c);
        $this->user_profile = $user_profile;
    }

}